/**
 * URL模块 - 提供URL相关的工具函数
 * 借鉴现代浏览器URL API和各种URL处理库
 */

/**
 * 获取URL查询参数
 * @param {string} name 参数名
 * @param {string} url URL字符串（可选，默认使用当前页面URL）
 * @returns {string|null} 参数值
 */
export function getQueryParam(name, url) {
  if (typeof name !== 'string') return null;

  const targetUrl = url || (typeof window !== 'undefined' ? window.location.href : '');

  try {
    const urlObj = new URL(targetUrl);
    return urlObj.searchParams.get(name);
  } catch {
    // 降级处理
    const regex = new RegExp(`[?&]${escapeRegExp(name)}=([^&#]*)`);
    const results = regex.exec(targetUrl);
    return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null;
  }
}

/**
 * 获取URL查询参数（忽略大小写）
 * @param {string} name 参数名
 * @param {string} url URL字符串（可选）
 * @returns {string|null} 参数值
 */
export function getQueryParamIgnoreCase(name, url) {
  if (typeof name !== 'string') return null;

  const targetUrl = url || (typeof window !== 'undefined' ? window.location.href : '');
  const lowerName = name.toLowerCase();

  try {
    const urlObj = new URL(targetUrl);
    for (const [key, value] of urlObj.searchParams) {
      if (key.toLowerCase() === lowerName) {
        return value;
      }
    }
    return null;
  } catch {
    // 降级处理
    const regex = new RegExp(`[?&]${escapeRegExp(name)}=([^&#]*)`, 'i');
    const results = regex.exec(targetUrl);
    return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null;
  }
}

/**
 * 获取所有查询参数
 * @param {string} url URL字符串（可选）
 * @returns {Object} 参数对象
 */
export function getAllQueryParams(url) {
  const targetUrl = url || (typeof window !== 'undefined' ? window.location.href : '');

  try {
    const urlObj = new URL(targetUrl);
    const params = {};
    for (const [key, value] of urlObj.searchParams) {
      if (params[key]) {
        if (Array.isArray(params[key])) {
          params[key].push(value);
        } else {
          params[key] = [params[key], value];
        }
      } else {
        params[key] = value;
      }
    }
    return params;
  } catch {
    // 降级处理
    const params = {};
    const search = targetUrl.indexOf('?');
    if (search === -1) return params;

    const queryString = targetUrl.substring(search + 1);
    const pairs = queryString.split('&');

    pairs.forEach(pair => {
      const [key, value = ''] = pair.split('=');
      if (key) {
        const decodedKey = decodeURIComponent(key.replace(/\+/g, ' '));
        const decodedValue = decodeURIComponent(value.replace(/\+/g, ' '));

        if (params[decodedKey]) {
          if (Array.isArray(params[decodedKey])) {
            params[decodedKey].push(decodedValue);
          } else {
            params[decodedKey] = [params[decodedKey], decodedValue];
          }
        } else {
          params[decodedKey] = decodedValue;
        }
      }
    });

    return params;
  }
}

/**
 * 构建查询字符串
 * @param {Object} params 参数对象
 * @returns {string} 查询字符串
 */
export function buildQueryString(params) {
  if (!params || typeof params !== 'object') return '';

  const pairs = [];

  Object.keys(params).forEach(key => {
    const value = params[key];
    const encodedKey = encodeURIComponent(key);

    if (Array.isArray(value)) {
      value.forEach(v => {
        pairs.push(`${encodedKey}=${encodeURIComponent(v)}`);
      });
    } else if (value !== null && value !== undefined) {
      pairs.push(`${encodedKey}=${encodeURIComponent(value)}`);
    }
  });

  return pairs.join('&');
}

/**
 * 添加查询参数到URL
 * @param {string} url 原URL
 * @param {Object} params 要添加的参数
 * @returns {string} 新URL
 */
export function addQueryParams(url, params) {
  if (!url || typeof url !== 'string') return '';
  if (!params || typeof params !== 'object') return url;

  try {
    const urlObj = new URL(url);
    Object.keys(params).forEach(key => {
      const value = params[key];
      if (Array.isArray(value)) {
        value.forEach(v => {
          urlObj.searchParams.append(key, v);
        });
      } else if (value !== null && value !== undefined) {
        urlObj.searchParams.set(key, value);
      }
    });
    return urlObj.toString();
  } catch {
    // 降级处理
    const queryString = buildQueryString(params);
    if (!queryString) return url;

    const separator = url.includes('?') ? '&' : '?';
    return url + separator + queryString;
  }
}

/**
 * 移除URL中的查询参数
 * @param {string} url 原URL
 * @param {string|string[]} keys 要移除的参数名
 * @returns {string} 新URL
 */
export function removeQueryParams(url, keys) {
  if (!url || typeof url !== 'string') return '';
  if (!keys) return url;

  const keysArray = Array.isArray(keys) ? keys : [keys];

  try {
    const urlObj = new URL(url);
    keysArray.forEach(key => {
      urlObj.searchParams.delete(key);
    });
    return urlObj.toString();
  } catch {
    // 降级处理
    let result = url;
    keysArray.forEach(key => {
      const regex = new RegExp(`[?&]${escapeRegExp(key)}=[^&#]*`, 'g');
      result = result.replace(regex, '');
    });

    // 清理多余的 & 和 ?
    result = result.replace(/[?&]&/g, '?').replace(/[?&]$/, '');
    return result;
  }
}

/**
 * 解析URL
 * @param {string} url URL字符串
 * @returns {Object|null} URL解析结果
 */
export function parseUrl(url) {
  if (!url || typeof url !== 'string') return null;

  try {
    const urlObj = new URL(url);
    return {
      href: urlObj.href,
      origin: urlObj.origin,
      protocol: urlObj.protocol,
      hostname: urlObj.hostname,
      host: urlObj.host,
      port: urlObj.port,
      pathname: urlObj.pathname,
      search: urlObj.search,
      searchParams: getAllQueryParams(url),
      hash: urlObj.hash
    };
  } catch {
    // 降级处理
    const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
    if (!match) return null;

    const [, , protocol, , authority, pathname, , search, , hash] = match;
    const [hostname, port] = (authority || '').split(':');

    return {
      href: url,
      origin: protocol && authority ? `${protocol}://${authority}` : '',
      protocol: protocol ? `${protocol}:` : '',
      hostname: hostname || '',
      host: authority || '',
      port: port || '',
      pathname: pathname || '',
      search: search ? `?${search}` : '',
      searchParams: getAllQueryParams(url),
      hash: hash ? `#${hash}` : ''
    };
  }
}

/**
 * 判断是否为绝对URL
 * @param {string} url URL字符串
 * @returns {boolean} 是否为绝对URL
 */
export function isAbsoluteUrl(url) {
  if (!url || typeof url !== 'string') return false;
  return /^[a-z][a-z\d+.-]*:/i.test(url);
}

/**
 * 判断是否为相对URL
 * @param {string} url URL字符串
 * @returns {boolean} 是否为相对URL
 */
export function isRelativeUrl(url) {
  return !isAbsoluteUrl(url);
}

/**
 * 连接URL路径
 * @param {...string} parts URL部分
 * @returns {string} 连接后的URL
 */
export function joinUrl(...parts) {
  if (parts.length === 0) return '';

  const validParts = parts.filter(part => part && typeof part === 'string');
  if (validParts.length === 0) return '';

  let result = validParts[0];

  for (let i = 1; i < validParts.length; i++) {
    const part = validParts[i];
    const resultEndsWithSlash = result.endsWith('/');
    const partStartsWithSlash = part.startsWith('/');

    if (resultEndsWithSlash && partStartsWithSlash) {
      result += part.slice(1);
    } else if (!resultEndsWithSlash && !partStartsWithSlash) {
      result += '/' + part;
    } else {
      result += part;
    }
  }

  return result;
}

/**
 * 规范化URL路径
 * @param {string} path URL路径
 * @returns {string} 规范化后的路径
 */
export function normalizePath(path) {
  if (!path || typeof path !== 'string') return '/';

  // 将反斜杠替换为斜杠
  path = path.replace(/\\/g, '/');

  // 分割路径
  const parts = path.split('/');
  const stack = [];

  parts.forEach(part => {
    if (part === '..') {
      if (stack.length > 0 && stack[stack.length - 1] !== '..') {
        stack.pop();
      } else if (!path.startsWith('/')) {
        stack.push('..');
      }
    } else if (part !== '.' && part !== '') {
      stack.push(part);
    }
  });

  let result = stack.join('/');

  // 保持原有的前导和尾随斜杠
  if (path.startsWith('/')) result = '/' + result;
  if (path.endsWith('/') && result !== '/') result += '/';

  return result || '/';
}

/**
 * 获取文件扩展名
 * @param {string} url URL或文件路径
 * @returns {string} 文件扩展名
 */
export function getFileExtension(url) {
  if (!url || typeof url !== 'string') return '';

  const pathname = parseUrl(url)?.pathname || url;
  const lastDot = pathname.lastIndexOf('.');
  const lastSlash = pathname.lastIndexOf('/');

  if (lastDot === -1 || lastDot < lastSlash) return '';

  return pathname.slice(lastDot + 1).toLowerCase();
}

/**
 * 获取文件名
 * @param {string} url URL或文件路径
 * @param {boolean} withExtension 是否包含扩展名
 * @returns {string} 文件名
 */
export function getFileName(url, withExtension = true) {
  if (!url || typeof url !== 'string') return '';

  const pathname = parseUrl(url)?.pathname || url;
  const lastSlash = pathname.lastIndexOf('/');
  const fileName = pathname.slice(lastSlash + 1);

  if (!withExtension) {
    const lastDot = fileName.lastIndexOf('.');
    return lastDot === -1 ? fileName : fileName.slice(0, lastDot);
  }

  return fileName;
}

/**
 * 转换相对URL为绝对URL
 * @param {string} relativeUrl 相对URL
 * @param {string} baseUrl 基础URL
 * @returns {string} 绝对URL
 */
export function resolveUrl(relativeUrl, baseUrl) {
  if (!relativeUrl || typeof relativeUrl !== 'string') return '';
  if (isAbsoluteUrl(relativeUrl)) return relativeUrl;

  try {
    return new URL(relativeUrl, baseUrl).href;
  } catch {
    // 简单的降级处理
    if (!baseUrl) return relativeUrl;
    return joinUrl(baseUrl, relativeUrl);
  }
}

/**
 * 正则表达式转义
 * @param {string} string 字符串
 * @returns {string} 转义后的字符串
 */
function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
